//
//  CheckIns.m
//  iCan - iPhone Context-Aware Navigation
//  Carnegie Mellon University - 18-842 Distributed Systems
//
//  Created by Andrew Santell on 3/26/12.
//  Copyright (c) 2012 Andrew Santell. All rights reserved.

/* View Controller that handles Check-ins and Check-outs */

#import "CheckIns.h"
#import "Users.h"
#import "iCanAppDelegate.h"
#import "Networking.h"
#import "SpinnerView.h"
#import "iCanViewController.h"

@interface CheckIns ()

@end

@implementation CheckIns

@synthesize textStatus;
@synthesize selected;
@synthesize checkbox;
@synthesize message, result;
@synthesize inputStream, outputStream;
@synthesize spinner;
@synthesize appDelegate;
@synthesize badCookie;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    myAvailable = TRUE; //Global Variable
    badCookie = FALSE;
    
    /* Set up user "global variables" */
    appDelegate = [[UIApplication sharedApplication] delegate];
	
    /*Reference - http://stackoverflow.com/questions/650131/checkbox-in-iphone-application - User: Cannyboy */
     
    /*Adding an 'Available' checkbox*/
    UIButton* checkBox = [[UIButton alloc] initWithFrame:CGRectMake(93,95,20,20)];  
    [checkBox setImage:[UIImage imageNamed:@"green.png"] forState:UIControlStateNormal];

    [checkBox addTarget:self action:@selector(toggleButton:) forControlEvents: UIControlEventTouchUpInside];
    [self.view addSubview:checkBox];
}

- (void)viewDidUnload
{
    [self setTextStatus:nil];
    [self setCheckbox:nil];
    [self setMessage:nil];
    [self setResult:nil];
    [self setInputStream:nil];
    [self setOutputStream:nil];
    [self setSpinner:nil];
    [self setAppDelegate:nil];
    [super viewDidUnload];
}

/* Available button */
- (void)toggleButton: (id) button
{
    selected = !selected;
    UIButton* check = (UIButton*) button;
    if (selected == NO)
    {
        [check setImage:[UIImage imageNamed:@"green.png"] forState:UIControlStateNormal];
        myAvailable = true;
    }
    else
    {
        [check setImage:[UIImage imageNamed:@"red.png"] forState:UIControlStateNormal];
        myAvailable = false;
    }
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
    
- (IBAction)checkIn:(id)sender 
{    

    
    if (self.textStatus.text.length < 160)
    {
        /* Set status entered in textbox to User's status */
        appDelegate.myStatus = self.textStatus.text;
        
        NSString *sanitizedStatus = [appDelegate.myStatus stringByReplacingOccurrencesOfString:@";" withString:@"%42"];
        
   
        /* Load spinner on top of screen until receiving network result */
        spinner = [[SpinnerView alloc] init];
        [spinner loadSpinnerIntoView:self.view];

        /*Populate message to send to server */
        message = @"check_in";
        message = [message stringByAppendingString:@";"];
        message = [message stringByAppendingString:appDelegate.myName];
        message = [message stringByAppendingString:@";"];
        message = [message stringByAppendingString:appDelegate.myCookie];
        message = [message stringByAppendingString:@";"];
        message = [message stringByAppendingString:sanitizedStatus];
        message = [message stringByAppendingString:@";"];
        if (myAvailable == true)
            message = [message stringByAppendingString:@"0"];
        if (myAvailable == false)
            message = [message stringByAppendingString:@"1"];
        message = [message stringByAppendingString:@";"];
        message = [message stringByAppendingString:@"\n"];
    
        /* Disable Back button while connecting to network */
        self.navigationController.navigationBar.userInteractionEnabled = NO;
    
        /* Initiate network connection */
        [self initNetworkCommunication];
    }
    else 
    {
         UIAlertView *lenAlert = [[UIAlertView alloc] initWithTitle:@"Max Length Exceeded" message:@"Please enter a status less than 160 characters"delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];   
        [lenAlert show];
    }
}

- (IBAction)checkOut:(id)sender 
{   
    /* Load spinner on top of screen until receiving network result */
    spinner = [[SpinnerView alloc] init];
    [spinner loadSpinnerIntoView:self.view];
    
    /*Populate message to send to server */
    message = @"check_out";
    message = [message stringByAppendingString:@";"];
    message = [message stringByAppendingString:appDelegate.myName];
    message = [message stringByAppendingString:@";"];
    message = [message stringByAppendingString:@"\n"];
   
    /* Disable Back button while connecting to network */
    self.navigationController.navigationBar.userInteractionEnabled = NO;
    
    /* Initiate network connection */
    [self initNetworkCommunication];
    
}

- (void) analyzeResult
{
 	/* Set up alert for errors */
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"You received an error from the network"delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
    UIAlertView *badCookieAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Your session has expired.  Please login again"delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
     
    /* The server should respond with "ACK" on all good Check-ins and Check-outs */
    NSLog(@"result = %@", result);
    
    if ([result isEqualToString:@"NACK"])
    { 
        NSLog(@"Error with received data");
        NSLog(@"Server responded with %@", result);
    
        /* Popup alert */
        [alert show];
    }
    else if ([result isEqualToString:@"BAD_COOKIE"])
    { 
        NSLog(@"Bad Cookie");
        badCookie = TRUE;
        [badCookieAlert show];
    }
    else if ([result isEqualToString:@"ACK"])
        NSLog(@"Success");
    
    result = NULL;    
}

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex   
{
    if (badCookie == TRUE)
    {
        badCookie = FALSE;
        result = NULL;
        iCanViewController *mainScreen = [self.storyboard instantiateViewControllerWithIdentifier:@"MainScreen"];
        [self presentViewController:mainScreen animated:YES completion:nil];
    }
}

- (BOOL)textFieldShouldReturn:(UITextField *)theTextField 
{
    if (theTextField == self.textStatus) 
    {
        [theTextField resignFirstResponder];
    }

    return YES;
}

/* Initiate network connection */
- (void) initNetworkCommunication
{

    NSLog(@"\nHost name = %@\nHost IP = %@\nHost Port = %lu", appDelegate.nodeName, appDelegate.nodeIP, appDelegate.nodePort);

    CFReadStreamRef readStream = NULL;
    CFWriteStreamRef writeStream = NULL;
    CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef) appDelegate.nodeIP, appDelegate.nodePort, &readStream, &writeStream);
    
    inputStream = (__bridge NSInputStream *) readStream;
    outputStream = (__bridge NSOutputStream *) writeStream;
    
    [inputStream setDelegate:self];
    [outputStream setDelegate:self];
    
    /* Put input and output streams into a run loop */
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    
    [inputStream open];
    [outputStream open];
    
    /* Put message into a format that can be sent across the network (NSData) */
    NSData *data = [[NSData alloc] initWithData:[message dataUsingEncoding:NSASCIIStringEncoding]];
    
    /* Send message to network */
    [outputStream write:[data bytes] maxLength:[data length]];
   
    
}

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent 
{
    /* Create error popup for failed connections */
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Could not connect to host"delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
    
    switch (streamEvent) 
    {
		case NSStreamEventOpenCompleted:
			NSLog(@"Stream opened");
			break;
            
        /* Accept return message from network */
		case NSStreamEventHasBytesAvailable:
            
            if (theStream == inputStream) 
            {
                
                uint8_t buffer[1024];
                int len;
                
                while ([inputStream hasBytesAvailable]) 
                {
                    len = [inputStream read:buffer maxLength:sizeof(buffer)];
                    if (len > 0) 
                    {
                        
                        result = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
                        
                        if (nil != result) 
                        {
                            NSLog(@"Response: %@", result);
                        }
                    }
                }
            }
			break;			
            
		case NSStreamEventErrorOccurred:
            
            NSLog(@"Can not connect to the host!");
            [inputStream close];
            [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [outputStream close];
            [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [spinner removeSpinner];
            [alert show];
            self.navigationController.navigationBar.userInteractionEnabled = YES;
			break;
            
		case NSStreamEventEndEncountered:
            NSLog(@"Closing Connection");
            [inputStream close];
            [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [outputStream close];
            [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            self.navigationController.navigationBar.userInteractionEnabled = YES;
            [spinner removeSpinner];
            [self analyzeResult];
			break;
            
		case NSStreamEventHasSpaceAvailable:
            NSLog (@"Output Buffer is Empty");
            break;
            
        default:
			NSLog(@"Unknown event");
            NSLog(@"Error Result (Should be NULL) = %@", result);
            [inputStream close];
            [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [outputStream close];
            [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [spinner removeSpinner];
            self.navigationController.navigationBar.userInteractionEnabled = YES;
            [alert show];
	}
}

@end
